package com.ruoyi.driver.ocrUnit;
import com.alibaba.fastjson2.JSONObject;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author:Max
 * @Date: 2025/8/18 17:13
 * @Description
 **/
public class BaiduOcrUtil {
    // 1. 百度AI平台获取
   private static final String API_KEY = "GMLQjjbca9zhN7cgkIA2vgDq";           // 百度API Key
    private static final String SECRET_KEY = "iwIfL0FUHsJX64CxOQYjVu4LfNBUlJ8Z";     // 百度Secret Key

    // 2. 全局缓存 access_token（有效期30天，建议加Redis缓存）
    private static String accessToken;

    // 3. 静态块：启动时获取 token
    static {
        getAccessToken();
    }

    /**
     * 获取百度 AI 的 access_token
     */
    private static void getAccessToken() {
        try {
            String url = "https://aip.baidubce.com/oauth/2.0/token";
            String param = "grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY;

            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            con.setDoOutput(true);

            // 发送请求
            OutputStream os = con.getOutputStream();
            os.write(param.getBytes("UTF-8"));
            os.flush();
            os.close();

            // 读取响应
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // 解析 JSON 获取 access_token
            String responseStr = response.toString();
            JSONObject json = JSONObject.parseObject(responseStr);
            accessToken = json.getString("access_token");

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("获取百度 access_token 失败，请检查 API Key 和 Secret Key");
        }
    }


    // 1. 身份证 OCR 识别（支持正面和反面）

    public static Map<String, Object> identifyIdCard(String imageBase64) {
        Map<String, Object> result = new HashMap<>();
        try {
            String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
            // 正面：姓名、性别、民族、出生、住址、公民身份号码
            // 反面：签发机关、有效期限
            String param = "id_card_side=front&image=" + URLEncoder.encode(imageBase64, "UTF-8");

            String requestUrl = url + "?access_token=" + accessToken;

            String response = sendHttpPost(requestUrl, param);
            String responseStr = response.toString();
            JSONObject json = JSONObject.parseObject(responseStr);

            if (json.containsKey("words_result")) {
                JSONObject words = json.getJSONObject("words_result");

                // 提取字段（注意：字段名可能不存在，需判断）
                result.put("name", getStringValue(words, "姓名"));
                result.put("idNumber", getStringValue(words, "公民身份号码"));
                result.put("address", getStringValue(words, "住址"));
                result.put("birth", getStringValue(words, "出生"));
                result.put("sex", getStringValue(words, "性别"));
                result.put("ethnic", getStringValue(words, "民族"));
            }

            // 如果是反面，识别签发机关和有效期
             if (param.contains("back")) {
                result.put("issue_org", getStringValue(json, "签发机关"));
                result.put("valid_date", getStringValue(json, "有效期限"));
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.put("error", "身份证识别失败：" + e.getMessage());
        }
        return result;
    }


    // 2. 驾驶证 OCR 识别

    public static Map<String, Object> identifyDriverLicense(String imageBase64) {
        Map<String, Object> result = new HashMap<>();
        try {
            String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/driving_license";
            String param = "image=" + URLEncoder.encode(imageBase64, "UTF-8");
            String requestUrl = url + "?access_token=" + accessToken;

            String response = sendHttpPost(requestUrl, param);
            String responseStr = response.toString();
            JSONObject json = JSONObject.parseObject(responseStr);

            if (json.containsKey("words_result")) {
                JSONObject words = json.getJSONObject("words_result");

                result.put("licenseNumber", getStringValue(words, "证号"));
                result.put("name", getStringValue(words, "姓名"));
                result.put("gender", getStringValue(words, "性别"));
                result.put("nationality", getStringValue(words, "国籍"));
                result.put("address", getStringValue(words, "住址"));
                result.put("birthDate", getStringValue(words, "出生日期"));
                result.put("issueDate", getStringValue(words, "初次领证日期"));
                result.put("validPeriod", getStringValue(words, "有效期限"));
                result.put("type", getStringValue(words, "准驾车型"));
                result.put("class", getStringValue(words, "准驾车型")); // 别名
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.put("error", "驾驶证识别失败：" + e.getMessage());
        }
        return result;
    }


    // 3. 行驶证 OCR 识别

    public static Map<String, Object> identifyVehicleLicense(String imageBase64) {
        Map<String, Object> result = new HashMap<>();
        try {
            String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license";
            String param = "image=" + URLEncoder.encode(imageBase64, "UTF-8");
            String requestUrl = url + "?access_token=" + accessToken;

            String response = sendHttpPost(requestUrl, param);
            String responseStr = response.toString();
            JSONObject json = JSONObject.parseObject(responseStr);

            if (json.containsKey("words_result")) {
                JSONObject words = json.getJSONObject("words_result");

                result.put("plateNumber", getStringValue(words, "号牌号码"));
                result.put("vehicleType", getStringValue(words, "车辆类型"));
                result.put("owner", getStringValue(words, "所有人"));
                result.put("address", getStringValue(words, "住址"));
                result.put("useCharacter", getStringValue(words, "使用性质"));
                result.put("model", getStringValue(words, "品牌型号"));
                result.put("vin", getStringValue(words, "车辆识别代号")); // VIN
                result.put("engineNo", getStringValue(words, "发动机号码"));
                result.put("registerDate", getStringValue(words, "注册日期"));
                result.put("issueDate", getStringValue(words, "发证日期"));
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.put("error", "行驶证识别失败：" + e.getMessage());
        }
        return result;
    }


    // 工具方法：安全获取 JSON 中的字符串值

    private static String getStringValue(JSONObject json, String key) {
        try {
            if (json.containsKey(key)) {
                return json.getJSONObject(key).getString("words");
            }
        } catch (Exception e) {
            // 忽略异常，返回空
        }
        return "";
    }


    // 发送 HTTP POST 请求

    private static String sendHttpPost(String url, String param) throws Exception {
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        con.setDoOutput(true);

        OutputStream os = con.getOutputStream();
        os.write(param.getBytes("UTF-8"));
        os.flush();
        os.close();

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        return response.toString();
    }


    // 测试入口

    public static void main(String[] args) throws IOException {
        // 测试：读取本地图片转 base64
        byte[] imageBytes = Files.readAllBytes(Paths.get("C:\\idcard.jpg"));
        String base64 = java.util.Base64.getEncoder().encodeToString(imageBytes);

        Map<String, Object> result = identifyIdCard(base64);
        System.out.println(result);
    }

}
